﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Abp;
using Abp.Authorization;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using Abp.ElasticSearch;
using Abp.ObjectMapping;
using Abp.Runtime.Caching;
using AutoMapper.QueryableExtensions;
using FwProject.Shop.Dto;
using FwProject.ShopApplication;
using FwProject.ShopApplication.Configuration;
using FwProject.ShoppingMall.Product;
using FwProject.ShoppingMall.Shop;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Nest;
using X.PagedList;

namespace FwProject.Shop
{
    /// <summary>
    /// 
    /// </summary>
    public class ShopTypeAppService : FwProjectAppServiceBase, IShopTypeAppService
    {
        private readonly IRepository<ShopType, Guid> _repositoryShopType;
        private readonly IRepository<ProductType, Guid> _repositoryProductType;
        private readonly IConfigurationRoot _appConfiguration;
        /// <summary>
        /// 
        /// </summary>
        public readonly ICacheManager _catchmanager;
        /// <summary>
        /// 
        /// </summary>
        public IGuidGenerator _guid { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public IObjectMapper _map { get; set; }


        /// <summary>
        /// 搜索引擎
        /// </summary>
        private readonly IElasticsearch _elasticsearch;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="repositoryShopType"></param>
        /// <param name="hostingEnvironment"></param>
        public ShopTypeAppService(IRepository<ShopType, Guid> repositoryShopType, IHostingEnvironment hostingEnvironment, IElasticsearch elasticsearch, IRepository<ProductType, Guid> repositoryProductType)
        {
            _repositoryShopType = repositoryShopType;
            _appConfiguration = hostingEnvironment.GetAppConfiguration();
            _repositoryProductType = repositoryProductType;
            _guid = SequentialGuidGenerator.Instance;
            _elasticsearch = elasticsearch;
        }

        #region 后台管理
        /// <summary>
        /// 获取一级分类列表
        /// </summary>
        public async Task<LayerDataBaseDto> GetPagedListAsync(string keyword)
        {
            var listmodel =  _repositoryShopType.GetAll().Where(o => o.Parentid == null);

            if (!string.IsNullOrEmpty(keyword))
                listmodel = listmodel.Where(o => o.TypeName.Contains(keyword));

            var model = await listmodel.OrderByDescending(o => o.CreationTime).ProjectTo<ShopTypeDto>().ToListAsync();
            LayerDataBaseDto dto = new LayerDataBaseDto();
            dto.Data = model;
            return dto;
        }
        /// <summary>
        /// 获取二级分类列表
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<LayerDataBaseDto> GetPagedList2Async(Guid Id, string keyword)
        {
            var listmodel = _repositoryShopType.GetAll().Where(o => o.Parentid == Id);

            if (!string.IsNullOrEmpty(keyword))
                listmodel = listmodel.Where(o => o.TypeName.Contains(keyword));

            var model = await listmodel.OrderByDescending(o => o.CreationTime).ProjectTo<ShopTypeDto>().ToListAsync();

            LayerDataBaseDto dto = new LayerDataBaseDto();
            dto.Data = model;
            return dto;
        }
        /// <summary>
        /// 获取一条分类信息不要加登录验证 搜索引擎需要使用
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ShopTypeDto> GetByIdAsync(Guid id)
        {
            var model = await _repositoryShopType.GetAsync(id);

            return _map.Map<ShopTypeDto>(model);
        }
        /// <summary>
        /// 获取所有一级分类
        /// </summary>
        /// <returns></returns>
        public async Task<List<ShopTypeDto>> GetParentListAsync()
        {
            var query = await _repositoryShopType.GetAll().Where(o => o.Parentid == null || o.Parentid == Guid.Empty).ToListAsync();

            return query.MapTo<List<ShopTypeDto>>();
        }

        /// <summary>
        /// 根据上级分类Id获取子分类信息
        /// </summary>
        /// <param name="parentid"></param>
        /// <returns></returns>
        public async Task<List<ShopTypeDto>> GetChildListByParentIdAsync(Guid parentid)
        {
            var list = await _repositoryShopType.GetAll().Where(o => o.Parentid == parentid).ToListAsync();
            return list.MapTo<List<ShopTypeDto>>();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [AbpAuthorize]
        public async Task<Guid> CreateAsync(ShopTypeInput input)
        {
            var entity = input.MapTo<ShopType>();
            entity.Id = _guid.Create();
            if (!string.IsNullOrWhiteSpace(input.TypeImg))
            {
                string FileTempPath = _appConfiguration["FileServicePath:TempShopType"];
                string FileSavaPath = _appConfiguration["FileServicePath:SavaShopType:SavaFilePath"];
                var path = SaveFile(input.TypeImg, FileTempPath, FileSavaPath, $"{DateTime.Now.ToString("yyyyMMdd")}/");
                entity.Piclogo = _appConfiguration["FileServicePath:SavaShopType:Virtual"] + path;
            }
            return await _repositoryShopType.InsertAndGetIdAsync(entity);
        }
        /// <summary>
        /// 返回分类型信息
        /// </summary>
        /// <returns></returns>
        public async Task<List<AppShopTypeDto>> GetAppAllListType(Guid? id)
        {
            SearchDescriptor<AppShopTypeDto> tquery = new SearchDescriptor<AppShopTypeDto>();
            var mustQuerys = new List<Func<QueryContainerDescriptor<AppShopTypeDto>, QueryContainer>>();
            if (id == null)
                tquery = tquery.Query(query => !query.Exists(e => e.Field(f => f.Parentid)));
            else
                tquery = tquery.Query(query => query.Match(m => m.Field(f => f.Id).Query(id.Value.ToString())));


            tquery = tquery.Sort(o => o.Descending(t => t.Orders));
            var model = await _elasticsearch.SearchAsync<AppShopTypeDto, Guid>(nameof(AppShopTypeDto).ToLower(), tquery, 0, 20);
            var list = model.Documents;
            return list.ToList();
        }

        /// <summary>
        /// 搜索引擎
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public AppShopTypeDto GetSerachType(Guid id)
        {

            var entity = _repositoryShopType.Get(id);
            var dto = entity.MapTo<AppShopTypeDto>();
            dto.ChildAppShopTypeDto = _repositoryShopType.GetAll().Where(o => o.Parentid == id && o.Isactive == true).ProjectTo<AppShopTypeDto>().ToList();
            return dto;

        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ShopTypeInput> GetByIdEnterAsync(Guid id)
        {
            var entity = await _repositoryShopType.GetAsync(id);
            var dto = entity.MapTo<ShopTypeInput>();

            dto.TypeImg = entity.Piclogo;
            return dto;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        [AbpAuthorize]
        public async Task ModifyAsync(Guid id, ShopTypeInput input)
        {
            var entity = await _repositoryShopType.GetAsync(id);
            var original = "";
            input.MapTo(entity);
            if (!string.IsNullOrEmpty(input.TypeImg))
            {
                if (!input.TypeImg.Contains("uploads"))
                {
                    if (!string.IsNullOrEmpty(entity.Piclogo))
                    {
                        var l = entity.Piclogo.Split('/');
                        original = l[l.Length - 1];
                    }
                    string FileTempPath = _appConfiguration["FileServicePath:TempShopType"];
                    string FileSavaPath = _appConfiguration["FileServicePath:SavaShopType:SavaFilePath"];
                    var path = SaveFile(input.TypeImg, FileTempPath, FileSavaPath, $"{DateTime.Now.ToString("yyyyMMdd")}/", original);
                    entity.Piclogo = _appConfiguration["FileServicePath:SavaShopType:Virtual"] + path;
                }
      
            }
            await _repositoryShopType.UpdateAsync(entity);
        }
        [AbpAuthorize]
        public async Task DeleteAsync(string ids)
        {
            string[] any = ids.Split('|');
            if (any.Any())
            {
                for (int i = 0; i < any.Count(); i++)
                    await _repositoryShopType.DeleteAsync(new Guid(any[i]));
            }
        }

        public async Task<string[]> GetCompleteTypeNameAsync(Guid id)
        {
            var type = await _repositoryShopType.GetAsync(id);
            string[] any = new string[2];
            if (type.Parentid.HasValue)
            {
                var parenttype = await _repositoryShopType.GetAsync(type.Parentid.Value);
                any[0] = parenttype.TypeName;
                any[1] = type.TypeName;
            }
            return any;

        }


        public async Task<string> SwitchActive(Guid id, bool active)
        {
            var t = "child";
            var entity = await _repositoryShopType.GetAsync(id);
            entity.Isactive = active;
            if (entity.Parentid == Guid.Empty || !entity.Parentid.HasValue)
            {
                var childs = _repositoryShopType.GetAll().Where(o => o.Parentid == entity.Id);
                t = "parent";
                foreach (var item in childs)
                {
                    item.Isactive = active;
                    await _repositoryShopType.UpdateAsync(item);
                }
            }

            await _repositoryShopType.UpdateAsync(entity);

            return t;
        }

        public async Task<List<ShopTypeOutputDto>> GetListAsync(Guid? id, string keyword)
        {
            var query = _repositoryShopType.GetAll().Where(o => o.Isactive&&o.Parentid==id);
            if (!string.IsNullOrEmpty(keyword))
                query = query.Where(o => o.TypeName.Contains(keyword));

            var list = await query.OrderByDescending(o => o.CreationTime).ProjectTo<ShopTypeOutputDto>().ToListAsync();
            return list;
        }
        #endregion
    }
}
